<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>6组合模式</title>
  </head>
  <body>
    1.组合模式就是用小的子对象来构建更大的对象，而这些小的子对象本身也许是由更 小的“孙对象”构成的。
    2.组合模式将对象组合成树形结构，以表示“部分整体”的层次结构
    <p>3. 定义一个大对象,添加小对象,最后遍历执行小对象)</p>

    <button id="btn">超级遥控器</button>
    <script>
      // 小对象
      const closeDoorCommand = {
        execute: function () {
          console.log('关门');
        },
      };
      // 小对象
      const openPcCommand = {
        execute: function () {
          console.log('开电脑');
        },
      };
      // 小对象
      const openQQCommand = {
        execute: function () {
          console.log('登录 QQ');
        },
      };

      // 大对象
      const MacroCommand = function () {
        return {
          commandsList: [],
          add: function (command) {
            this.commandsList.push(command);
          },
          execute: function () {
            for (let i = 0, command; (command = this.commandsList[i++]); ) {
              command.execute();
            }
          },
        };
      };
      const macroCommand = MacroCommand();
      macroCommand.add(closeDoorCommand);
      macroCommand.add(openPcCommand);
      macroCommand.add(openQQCommand);
      macroCommand.execute();

      // ============更强大的宏命令============
      const btn = document.getElementById('btn');
      // 定义宏命令
      function MacroCommand() {
        return {
          commandsList: [],
          add(command) {
            this.commandsList.push(command);
          },
          execute() {
            this.commandsList.map((item) => {
              item.execute();
            });
          },
        };
      }

      // 打开空调
      const openAc = {
        execute() {
          console.log('打开空调');
        },
      };

      // 打开电视和打开音响的命令
      const openTv = {
        execute() {
          console.log('打开电视');
        },
      };

      const openSound = {
        execute() {
          console.log('打开音响');
        },
      };

      const macroCommand1 = MacroCommand();
      macroCommand1.add(openTv);
      macroCommand1.add(openSound);

      // 关门、打开电脑、登陆 QQ 的命令
      const closeDoor = {
        execute() {
          console.log('关门');
        },
      };

      const openPc = {
        execute() {
          console.log('打开电脑');
        },
      };

      const loginQQ = {
        execute() {
          console.log('登陆QQ');
        },
      };

      const macroCommand2 = MacroCommand();
      macroCommand2.add(closeDoor);
      macroCommand2.add(openPc);
      macroCommand2.add(loginQQ);

      // 组合成为超级命令
      const macroCommand = MacroCommand();
      macroCommand.add(openAc);
      macroCommand.add(macroCommand1);
      macroCommand.add(macroCommand2);

      document.getElementById('btn').addEventListener('click', () => {
        macroCommand.execute();
      });

      // 打开空调
      // 打开电视
      // 打开音响
      // 关门
      // 打开电脑
      // 登陆QQ
    </script>
  </body>
</html>
